// Package inventory @Title inventory[简述该包的主要作用]
// @Description
// @Author  cnHuaShao
// @since v0.0.1
// @Version v1.0.0
// @Date 2024/5/1 23:30
// @Update 2024/5/1 23:30
package inventory

import (
	"FinancialManagement/src/base/baselog"
	"FinancialManagement/src/base/db"
	"database/sql"
	"errors"
	"fmt"
	"go.uber.org/zap"
	"gopkg.in/guregu/null.v3"
	"gorm.io/gorm"
)

// CreateInventoryType
// @Description: 创建库存类型
// @param inventoryType
// @return error
func CreateInventoryType(inventoryType InventoryType) error {
	return db.Res.DB.GetDbW().Create(&inventoryType).Error
}

// GetInventoryType
// @Description: 获取指定库存类型信息
// @param typeID 库存类型编号
// @return *InventoryType
// @return error
func GetInventoryType(typeID int) (*InventoryType, error) {
	var inventoryType InventoryType
	result := db.Res.DB.GetDbW().First(&inventoryType, typeID)
	if errors.Is(result.Error, gorm.ErrRecordNotFound) {
		return nil, errors.New("inventory type not found")
	}
	return &inventoryType, result.Error
}

// GetSubclassInventoryTypeCount
// @Description: 获取当前主类型下子类的数量
// @param parentTypeID
// @return count
// @return err
func GetSubclassInventoryTypeCount(parentTypeID int) (count int64, err error) {
	err = db.Res.DB.GetDbR().Model(&InventoryType{}).Where("parent_type_id", parentTypeID).Count(&count).Error
	return count, err
}

// UpdateInventoryType
// @Description: 修改库存类型内容
// @param typeID 要修改的库存类型编号
// @param typeName
// @param typeDescription
// @param unit
// @param parentTypeID
// @return *InventoryType
// @return error
func UpdateInventoryType(typeID uint, typeName, typeDescription, unit string, parentTypeID int) (*InventoryType, error) {
	var inventoryType InventoryType
	result := db.Res.DB.GetDbW().First(&inventoryType, typeID)
	if errors.Is(result.Error, gorm.ErrRecordNotFound) {
		return nil, errors.New("找不到库存类型")
	}
	inventoryType.TypeName = typeName
	inventoryType.TypeDescription = null.String{sql.NullString{
		String: typeDescription,
		Valid:  typeDescription != "",
	}}
	inventoryType.Unit = null.String{sql.NullString{
		String: unit,
		Valid:  unit != "",
	}}
	inventoryType.ParentTypeID = parentTypeID
	result = db.Res.DB.GetDbW().Save(&inventoryType)
	return &inventoryType, result.Error
}

// DeleteInventoryType
// @Description: 删除指定库存类型
// @param typeID
// @return error
func DeleteInventoryType(typeID int) error {
	result := db.Res.DB.GetDbW().Delete(&InventoryType{}, typeID)
	return result.Error
}

// GetAllInventoryTypes
// @Description: 获取所有库存类型
// @param typeName 模糊查询库存类型名称
// @return []InventoryType
// @return error
func GetAllInventoryTypes(typeName string) ([]InventoryType, error) {
	var inventoryTypes []InventoryType
	sqlWhere := " 1=1 "
	if typeName != "" {
		sqlWhere = fmt.Sprintf("%s and type_name like '%%%s%%'", sqlWhere, typeName)
	}
	sql := fmt.Sprintf("select i.type_id,i.type_name,i.type_description,i.parent_type_id,(select it.type_name from inventory_type as it where it.type_id=i.parent_type_id) as parentTypeName,i.unit,i.created_at from inventory_type as i where %s order by i.type_id desc", sqlWhere)
    res, err := db.Res.DB.GetDbR().Raw(sql).Rows()
    if err != nil {
        return nil, err
    }
    defer res.Close()
    for res.Next() {
        var inventory InventoryType
        scErr := res.Scan(&inventory.TypeID, &inventory.TypeName, &inventory.TypeDescription, &inventory.ParentTypeID, &inventory.ParentTypeName, &inventory.Unit, &inventory.CreatedAt)
        if scErr != nil {
            baselog.Logger.Error("解析错误", zap.Error(scErr))
        }
        inventoryTypes = append(inventoryTypes, inventory)
    }
    return inventoryTypes, nil
}
